/**
 * Copyright 2012 Facebook
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.socool.login;

import java.io.BufferedReader;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.Hashtable;
import java.util.Stack;

import org.json.JSONArray;
import org.json.JSONObject;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.BaseAdapter;

import com.facebook.android.Util;

/*
 * Fetch friends profile pictures request via AsyncTask
 */
public class FriendsGetProfilePics {

    Hashtable<String, Bitmap> friendsImages;
    Hashtable<String, String> positionRequested;
    BaseAdapter listener;
    int runningCount = 0;
    Stack<ItemPair> queue;

    /*
     * 15 max async tasks at any given time.
     */
    final static int MAX_ALLOWED_TASKS = 15;

    public FriendsGetProfilePics() {
        friendsImages = new Hashtable<String, Bitmap>();
        positionRequested = new Hashtable<String, String>();
        queue = new Stack<ItemPair>();
    }

    /*
     * Inform the listener when the image has been downloaded. listener is
     * FriendsList here.
     */
    public void setListener(BaseAdapter listener) {
        this.listener = listener;
        reset();
    }

    public void reset() {
        positionRequested.clear();
        runningCount = 0;
        queue.clear();
    }

    /*
     * If the profile picture has already been downloaded and cached, return it
     * else execute a new async task to fetch it - if total async tasks >15,
     * queue the request.
     */
    public Bitmap getImage(String uid, String url) {
        Bitmap image = friendsImages.get(uid);
        if (image != null) {
            return image;
        }
        if (!positionRequested.containsKey(uid)) {
            positionRequested.put(uid, "");
            if (runningCount >= MAX_ALLOWED_TASKS) {
                queue.push(new ItemPair(uid, url));
            } else {
                runningCount++;
                new GetProfilePicAsyncTask().execute(uid, url);
            }
        }
        return null;
    }

    public void getNextImage() {
        if (!queue.isEmpty()) {
            ItemPair item = queue.pop();
            new GetProfilePicAsyncTask().execute(item.uid, item.url);
        }
    }

    /*
     * Start a AsyncTask to fetch the request
     */
    private class GetProfilePicAsyncTask extends AsyncTask<Object, Void, Bitmap> {
        String uid;

        @Override
        protected Bitmap doInBackground(Object... params) {
            this.uid = (String) params[0];
            String url = (String) params[1];
            return getBitmap(url);
        }

        @Override
        protected void onPostExecute(Bitmap result) {
            runningCount--;
            if (result != null) {
                friendsImages.put(uid, result);
                listener.notifyDataSetChanged();
                getNextImage();
            }
        }
    }

    class ItemPair {
        String uid;
        String url;

        public ItemPair(String uid, String url) {
            this.uid = uid;
            this.url = url;
        }
    }
    
    public static Bitmap getBitmap(String userId) {
        Bitmap bm = null;
       
        try {
        //String str_url = "https://graph.facebook.com/"+userId+"/picture";
        String str_url = "https://graph.facebook.com/"+userId+"/picture?redirect=false";
        
        	
       // String str_url=	"https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash4/372183_100002526091955_998385602_q.jpg";
        
        URL url; 
        URLConnection conn;
        InputStream is;
        /*
        url= new URL(str_url);
        
        conn = url.openConnection();
      	conn.connect();
       is = conn.getInputStream();
       
       String line;
       BufferedReader br = new BufferedReader(new InputStreamReader(is)); 
       StringBuilder sb = new StringBuilder(); 
      while ((line = br.readLine()) != null) 
         sb.append(line + '\n'); 
       JSONObject obj = Util.parseJson(sb.toString());
       JSONObject o = obj.getJSONObject("data");
      
       String url_pic="aa";
       url_pic = o.getString("url");
   	   Log.d("test", "url_pic : "+ url_pic);
   	   */
   	 //url = new URL(url_pic);
   	url = new URL("http://graph.facebook.com/"+userId+"/picture?type=square");
     
    conn = url.openConnection();
   	conn.connect();
    is = conn.getInputStream();
       // BufferedInputStream bis = new BufferedInputStream(is);
      // bm = BitmapFactory.decodeStream(bis);
        bm = BitmapFactory.decodeStream(new FlushedInputStream(is));
       // bis.close();
        is.close();
        } catch (Exception e) {
			// TODO Auto-generated catch block
		e.printStackTrace();
		Log.d("test", "Error: "+e.getMessage());
		}
        
        return bm;
    }
    

    static class FlushedInputStream extends FilterInputStream {
        public FlushedInputStream(InputStream inputStream) {
            super(inputStream);
        }

        @Override
        public long skip(long n) throws IOException {
            long totalBytesSkipped = 0L;
            while (totalBytesSkipped < n) {
                long bytesSkipped = in.skip(n - totalBytesSkipped);
                if (bytesSkipped == 0L) {
                    int b = read();
                    if (b < 0) {
                        break; // we reached EOF
                    } else {
                        bytesSkipped = 1; // we read one byte
                    }
                }
                totalBytesSkipped += bytesSkipped;
            }
            return totalBytesSkipped;
        }
    }

}
